
	/************************************************************************************************
	 	
		Factory: jsl.Date

		Factories:	
			d			Date							(date*)								- sid: 8.0			
			d			fromLString				(s, fid*)							- sid: 8.0
				
		Static:
			obj		setFormat					(fid,pattern)					- sid: 8.0
			ptn		getFormat					(fid)									- sid: 8.0			
			b			isDate						(s, fid*)							- sid: 8.0
							
		Locales:			
			d			setLocale					(id*)									- sid: 8.0	
			id		getLocale					()										- sid: 8.0

		Format:						
			d			setFormat					(fid*)								- sid: 8.0
			fid		getFormat					()										- sid: 8.0			
			s			toLString					(fid*)								- sid: 8.0
		
		TimeZone:
			b			useDst						()										- sid: 8.0
			b			isInDst						()										- sid: 8.0			
			d			getDstStart				()										- sid: 8.0
			d			getDstEnd					()										- sid: 8.0
			obj		getTimeZone				(dst*)								- sid: 8.0
							
		Moving:
			d			move							(units, clone*)				- sid: 5.0
			d			toFirstDayOfWeek	(clone*)							- sid: 5.0
			d			toLastDayOfWeek		(clone*)							- sid: 5.0
			d			toFirstDayOfMonth	(clone*)							- sid: 5.0
			d			toLastDayOfMonth	(clone*)							- sid: 5.0
			d			toFirstDayOfYear	(clone*)							- sid: 5.0
			d			toLastDayOfYear		(clone*)							- sid: 5.0
					
		Info:
			b			isInLeapYear			()										- sid: 8.0
			b			between						(date1, date2)				- sid: 8.0							
			n			distance					(date, unit*)					- sid: 8.0			
			
			n			getDaysOfMonth		()										- sid: 8.0			
			n			getDaysOfYear			()										- sid: 8.0			
			
			n			getDayOfWeek			()										- sid: 3.0
			n			getDayOfYear			()										- sid: 3.0
			n			getWeekOfMonth		()										- sid: 3.0		
			n			getWeekOfYear			()										- sid: 8.0			
											
		Legend:
		
		fid				f|s+			format id or format inline string/function 
		pattern		f|s+			format inline string or function f(d|s+, type) { ... }
		date			d
		units			s+
		timezone 	obj				{ abbreviation, offsetS, offsetN, offsetH, offsetM }		
		
		Format rule:
			data format or data locale + public or sys locale  + puiblic
		
		units:	y, m, w, d, h, mn, s, ms
			
			example: -2y 3m -1h-3mn-1s-2ms
			example: ldw-2y3m1h3mn1s2ms
			example: 2years3months1hours3minutes1seconds2milliseconds
											
		format:	
			
			days:			
				DAY 		- uppercase full day name
				Day 		- mixedcase full day name
				day 		- lowercase full day name
										
				DY			- uppercase short day name 
				Dy			- mixedcase short day name 
				dy			- lowercase short day name 

				dw			- day number in the week (1-7)
			 ddw			- day number in the week (1-7) with zero padding

				d				- day number in the month (1-31)
				dd			- day number in the month (1-31) with zero padding

			 dyy			- day number in the year (1-366)
			 ddy			- day number in the year (1-366) with zero padding
			
			 sf				- day suffix (1st, 2nd, 3rd, 4th, ...)	
			 
			weeks:
 				wm			- week number in the month (1-5)		
			 wwm			- week number in the month (1-5)	with zero padding

				wy			- week 	number in the year (1-53)
			 wwy			- week 	number in the year (1-53) with zero padding								
						
			months:							
				MONTH		- uppercase full month name
				Month		- mixedcase full month name
				month		- lowercase full month name
	
				MT			- uppercase short month name 
				Mt			- mixedcase short month name 
				mt			- lowercase short month name 

				 m			- month number in the year (1-12)
			  mm			- month number in the year (1-12) with zero padding
			
			years:
				 y			- last 2 digits of year 
				yy			- last 2 digits of year with zero padding
			yyyy			- year 4 digits
										
			time:			
				h				- hour of day(1-12) 
				hh			- hour of day(1-12) with zero padding
			 	H				-	hour of day(0-23)  
				HH			- hour of day(0-23) with zero padding
				mn			- minutes (0-59)
				mmn			- minutes (0-59) with zero padding
				s				- seconds (0-59)
				ss			- seconds (0-59) with zero padding
				ms			- milliseconds (0-999)
				mms			- milliseconds (0-999) with zero padding
				
				MR			- uppercase meridian indicator	(AM, PM)
				mr			- lowercase meridian indicator 	(am, pm)
		
		timezone:											
				z				- UTC time zone offset 										ex: +0100
				zs			- UTC time zone offset short							ex: +01
				z:			- UTC time zone offset with : separator		ex: +01:00
				za			- UTC time zone abbreviation 
				
		Note:
			All other mask symbol are treated as literal
						
	************************************************************************************************/
	
	//-------------------------------------------------------------------------------
  jsl.Date = function(date) {
  	try {  		
  		var proto, rv
			//@d[  		
	    if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(date, "d", "date")//@d]
			
			if(arguments.length) 				
				if(date.__augmented) 	return date
				else									rv = date
			else
				rv = new Date
													    			 	    	    
			proto = jsl.Date.prototype
			
    	for(var id in proto)
    		if(proto.hasOwnProperty(id))
					rv[id] = proto[id]
			
			rv.__native = arguments.callee.__native			
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
  }
  //-------------------------------------------------------------------------------
	jsl.Date.prototype	= jsl.Object()
	jsl.Date.__name			= "jsl.Date" 
	jsl.Date.__f				= "date"	
	jsl.Date.__fs				= {  
		
		date:						null,
		date_l:					null,
		time:						null,
		time_l:					null,
		month_day:			null,
		month_year:			null,
		
		//iso8601
		iso8601:				"yyyy-mm-dd",
    iso8601_l:			"yyyy-mm-dd hh:mmn:ssz",
		
		iso8601_time:		"HH:mmn",
		iso8601_time_l:	"HH:mmn:ss",
				
    iso8601_yd:			"yyyy-ddy",
    iso8601_ym:			"yyyy-mm",
    iso8601_yw:			"yyyy-Wwwy",
    iso8601_ywd:		"yyyy-Wwwy-dw"
	}
	//constants
  //-------------------------------------------------------------------------------
	jsl.Date.MILLISECOND 	= 1
	jsl.Date.SECOND 			= jsl.Date.MILLISECOND 	* 1000
	jsl.Date.MINUTE 			= jsl.Date.SECOND				* 60
	jsl.Date.HOUR				 	= jsl.Date.MINUTE				* 60
	jsl.Date.DAY 					= jsl.Date.HOUR					* 24 
	jsl.Date.WEEK 				= jsl.Date.DAY					* 7

	//gregorian calendar with leaps year every 4 and -3 every 400 years
	//year average in days: 365.2425  
	//we still use simple numbers to avoid that moving a date of n month move also h, m etc..
	jsl.Date.YEAR 				= jsl.Date.DAY					* 365 //365.2425							
	jsl.Date.MONTH 				= jsl.Date.DAY					* 30	//30.436875
  //-------------------------------------------------------------------------------
	jsl.defineError("jsl.DateError")	
  //-------------------------------------------------------------------------------
	jsl.Date.fromLString = function(s, fid) {
		try {
			var l, fs, rv, fm, re, re2, li, ds, data, mtc
			var y, m, wy, wm, d, dw, dy, h, H, mn, sn, ms, mr, n, dt, f, sf, z, d1, m1, dt2, za
			
			//@d[
			if(!arguments.length || arguments.length > 3)	throw jsl.ParamError()
			jsl.validate(s, "s+", "s")
			if(arguments.length === 2)	jsl.validate(fid					, "f|s+", "fid")
			if(arguments.length > 2)		jsl.validate(fid					, "s+"	, "locale")
			if(arguments.length > 2)		jsl.validate(arguments[2]	, "s+"	, "fid")//@d]
				
			jsl.require("locale")	
			l = jsl.Locale.get()
			
			//1° - public formats									
			if(!fid) {				
				fs = jsl.Object.clone(this.__fs)
				jsl.Object.walk(fs, function(id, v) { if(!v) this[id] = l.d_formats[id] }) 
			}
			
			//2° - inline function format
			else if(jsl.isFunction(fid))	{
				try 			{ rv = fid(s + "")													}
				catch(e) 	{ throw jsl.ScriptError("BadScript:fid", e) }

				//@d[									
				if(!jsl.isDate(rv))	throw jsl.ParamError("BadReturnType:fid:Date")//@d]				
				fs = {}
			}					
			
			//3° - inline format id
			else if(this.__fs.hasOwnProperty(fid)) {
			
				fm = this.__fs[fid]
				if(!fm) fm = l.d_formats[fid]										
				fs = { fm: fm }					
			}
			
			//4° - inline locale 
			else if(arguments.length === 3 || jsl.Locale.isDefined(fid)) {

				//@d[
				if(!jsl.Locale.isDefined(fid))	throw jsl.ParamError("NotDefined:locale(fid)")//@d]
				l	= jsl.Locale.get(fid)
								
				if(!arguments[2]) {
					fs = jsl.Object.clone(this.__fs)
					jsl.Object.walk(fs, function(id, v) { if(!v) this[id] = l.d_formats[id] }) 
				}
				else if(l.d_formats[arguments[2]])	fs = { fm: l.d_formats[arguments[2]] }
				else																fs = { fm: arguments[2] }				
			}
			//5° - inline string format 
			else 
				fs = { fm: fid }															

			re	= "(\\\\)*(DAY|Day|dyy|day|DY|Dy|dy|MONTH|Month|month|MT|Mt|mt|MR|mr|hh|h|HH|H|mmn|mn|sf|ss|s|mms|ms|dw|ddw|" +
					 	"ddy|dd|d|wm|wwm|wy|wwy|mm|m|yyyy|yy|y|za|zs|z:|z|$)"
						
			re  = RegExp(re, "g")
			re2	= RegExp((re + "").slice(1, -2)) //-> -2 global flag
			f		= function(s, g1, g2){ return g1 && g1.length % 2 ? g1.slice(0, -1) + g2 : s }

			for(var id in fs) 
				if(fs.hasOwnProperty(id)) {
					
					fm = fs[id]		

					if(jsl.isFunction(fm)) {
						
						try 			{ rv = fm(s + "")	}
						catch(e) 	{ continue 				}
		
						//@d[									
						if(!jsl.isDate(rv))	throw jsl.ParamError("BadReturnType:locale[" + l.id + "\\:" + id + "]:Date")//@d]				
						break
					}
							
					re.lastIndex 	= 0
					li						= 0
					ds						= s + ""					
					dw = d = dy 	= sf = wm = wy = m = y = mr = h = H = mn = sn = ms = z = za = null
							
					parsing:
					while((mtc = re.exec(fm))) {		
						
						//no look-beahind re in js
						if(mtc[1])
							if(mtc[1].length % 2) mtc.index += mtc[0].length, mtc[2] = null
							else									mtc.index += mtc[1].length
						
						if(mtc.index > li) {
							
							data = ds.match("^" + fm.slice(li, mtc.index).replace(re2, f).replace(/[\^\$\.\*\+\?\=\!\:\|\\\/\(\)\[\]\{\}]/g, "\\$&"))
								
							if(!data) break
							ds = ds.slice(data[0].length)
							if(!mtc[2]) {
								li = re.lastIndex
								continue
							}
						}
										
						data = null
						
						switch(mtc[2]) {
							
							//days
			 				//-------------------------------------------------------------------------------
							case "DAY":						
							case "day":	
							case "Day":	
								
								data 	= l.d_days.join("|").toLowerCase()								
								dt 		= ds.match(RegExp("^" + data, "i"))

								if(!dt) break parsing																			
								n 		= jsl.Array.index(data.split("|"), dt[0].toLowerCase())
								
								if(dw != null && dw !== n)	throw jsl.DateError("lang.InconsistentDate:s(dw)")
								dw		= n
								data 	= dt
								break
							
							case "DY":						
							case "dy":	
							case "Dy":	
								
								data 	= l.d_days_short.join("|").toLowerCase()								
								dt 		= ds.match(RegExp("^" + data, "i"))

								if(!dt) break parsing																			
								n 		= jsl.Array.index(data.split("|"), dt[0].toLowerCase())

								if(dw != null && dw !== n)	throw jsl.DateError("lang.InconsistentDate:s(dw)")
								dw		= n
								data 	= dt
								break
							
							case "dw":						data = ds.match(/^[1234567]/)
							case "ddw": if(!data)	data = ds.match(/^0[1234567]/)
							
								if(!data) 			break parsing																			
								n = +data[0] - 1 								
								n = (n + l.d_first_wday) % 7
								
								if(dw != null && dw !== n)	throw jsl.DateError("lang.InconsistentDate:s(dw)")
								dw = n
								break

							case "d":							data = ds.match(/^\d{1,2}/)
							case "dd":	if(!data) data = ds.match(/^\d{2}/)

								if(!data) 		break parsing																			
								n	= +data[0]
								
								try 			{ jsl.validate(n, "i[1,31]") 	}
								catch(e) 	{ break parsing 							}				
								
								if(d != null && d !== n)	throw jsl.DateError("lang.InconsistentDate:s(d)")
								d = n				
								break

							case "dyy":						data = ds.match(/^\d{1,3}/)
							case "ddy":	if(!data)	data = ds.match(/^\d{3}/)
							
								if(!data) 			break parsing																			
								n = +data[0]
								
								try 			{ jsl.validate(n, "i[1,366]") 	}
								catch(e) 	{ break parsing 								}								

								if(dy != null && dy !== n)	throw jsl.DateError("lang.InconsistentDate:s(dy)")
								dy = n
								break
							
							case "sf":

								data = ds.match(RegExp(l.d_days_ordinals.join("|"), "i"))								
								if(!data) break parsing																			
								
								if(sf != null && sf !== data[0])	throw jsl.DateError("lang.InconsistentDate:s(sf)")
								sf = data[0]
								break
								
							//weeks	
			 				//-------------------------------------------------------------------------------
							case "wm":						data = ds.match(/^[12345]/)
							case "wwm":	if(!data)	data = ds.match(/^0[12345]/)

								if(!data) break parsing
								n = +data[0]

								if(wm != null && wm !== n)	throw jsl.DateError("lang.InconsistentDate:s(wm)")
								wm = n
								break

							case "wy":						data = ds.match(/^\d{1,2}/)
							case "wwy":	if(!data)	data = ds.match(/^\d{2}/)

								if(!data) break parsing
								n = +data[0]

								try				{ jsl.validate(n, "i[1,53]") }
								catch(e) 	{ break parsing 							}								

								if(wy != null && wy !== n)	throw jsl.DateError("lang.InconsistentDate:s(wy)")
								wy = n
								break
																				
							//months	
			 				//-------------------------------------------------------------------------------
							case "MONTH":						
							case "month":	
							case "Month":	
								
								data 	= l.d_months.join("|").toLowerCase()								
								dt 		= ds.match(RegExp("^" + data, "i"))
								if(!dt) break parsing																			
								n 		= jsl.Array.index(data.split("|"), dt[0].toLowerCase())

								if(m != null && m !== n)	throw jsl.DateError("lang.InconsistentDate:s(m)")
								m			= n
								data 	= dt
								break
								
							case "MT":						
							case "mt":	
							case "Mt":	
								
								data 	= l.d_months_short.join("|").toLowerCase()								
								dt 		= ds.match(RegExp("^" + data, "i"))

								if(!dt) break parsing																			
								n 		= jsl.Array.index(data.split("|"), dt[0].toLowerCase())

								if(m != null && m !== n)	throw jsl.DateError("lang.InconsistentDate:s(m)")
								m			= n
								data 	= dt
								break								

							case "m":							data = ds.match(/^\d{1,2}/)
							case "mm":	if(!data)	data = ds.match(/^\d{2}/)

								if(!data) 		break parsing																											
								n	= +data[0] - 1
								
								try 			{ jsl.validate(n, "i[0,11]") 	}
								catch(e) 	{ break parsing 							}								

								if(m != null && m !== n)	throw jsl.DateError("lang.InconsistentDate:s(m)")
								m	= n
								break

							//years	
			 				//-------------------------------------------------------------------------------
							case "yyyy": 						data = ds.match(/^\d{4}/)
							case "yy":		if(!data) data = ds.match(/^\d{2}/)
							case "y":			if(!data) data = ds.match(/^\d{1,2}/)

								if(!data) 		break parsing
								n = data[0]
								
								if(n.length === 1)			n = ((new Date).getFullYear() + "").slice(0, -2) + "0" + n	
								else if(n.length === 2)	n = ((new Date).getFullYear() + "").slice(0, -2) + n
																											
								n	= +n	
																							
								if(y != null && y !== n)	throw jsl.DateError("lang.InconsistentDate:s(y)")
								y	= n
								break
								
							//time	
			 				//-------------------------------------------------------------------------------
							case "MR":
							case "mr":

								data = ds.match(RegExp("^" + l.d_am + "|" + l.d_pm, "i"))
								if(!data) break parsing																			
												
								n = data[0].toLowerCase() === l.d_am.toLowerCase() ? 1 : 2
								
								if(mr != null && mr !== n)	throw jsl.DateError("lang.InconsistentDate:s(mr)")
								mr = n
								break

							case "h":							data = ds.match(/^\d{1,2}/)
							case "hh":	if(!data)	data = ds.match(/^\d{2}/)
							
								if(!data) break parsing																			
								n	= +data[0]
								
								try 			{ jsl.validate(n, "i[1,12]") 	}
								catch(e) 	{ break parsing 							}

								if(h != null && h !== n)	throw jsl.DateError("lang.InconsistentDate:s(h)")
								h = n
								break							

							case "H":							data = ds.match(/^\d{1,2}/)
							case "HH":	if(!data)	data = ds.match(/^\d{2}/)

								if(!data) break parsing																			
								n	= +data[0]

								try 			{ jsl.validate(n, "i[0,23]")	}
								catch(e) 	{ break parsing 							}
							
								if(H != null && H !== n)	throw jsl.DateError("lang.InconsistentDate:s(h)")
								H = n
								break							

							case "mn":						data = ds.match(/^\d{1,2}/)
							case "mmn":	if(!data)	data = ds.match(/^\d{2}/)

								if(!data) break parsing																			
								n = +data[0]

								try 			{ jsl.validate(n, "i[0,59]")	}
								catch(e) 	{ break parsing 							}
								
								if(mn != null && mn !== n)	throw jsl.DateError("lang.InconsistentDate:s(mn)")
								mn = n
								break						
									
							case "s":							data = ds.match(/^\d{1,2}/)
							case "ss":	if(!data)	data = ds.match(/^\d{2}/)

								if(!data) 			break parsing																											
								n = +data[0]

								try 			{ jsl.validate(n, "i[0,59]")	}
								catch(e) 	{ break parsing 							}

								if(sn != null && sn !== n)	throw jsl.DateError("lang.InconsistentDate:s(sn)")
								sn = n
								break
															
							case "ms":						data = ds.match(/^\d{1,3}/)
							case "mms":	if(!data)	data = ds.match(/^\d{3}/)

								if(!data) 			break parsing																			
								n = +data[0]

								try 			{ jsl.validate(n, "i[0,999]")	}
								catch(e) 	{ break parsing 							}

								if(ms != null && ms !== n)	throw jsl.DateError("lang.InconsistentDate:s(ms)")
								ms = n
								break								
							
							case "z":							
								data = ds.match(/^(\+|\-)\d{4}/)							
								if(!data) break parsing																			
								 
								if(z != null && z !== data[0])	throw jsl.DateError("lang.InconsistentDate:s(z)")
								z	= data[0]
								break
							
							case "zs":	
								data = ds.match(/^(\+|\-)\d{2}/)
								if(!data) break parsing																			
								 
								if(z != null && z !== data[0] + "00")	throw jsl.DateError("lang.InconsistentDate:s(z)")
								z	= data[0] + "00"
								break
							
							case "z:":	
								data = ds.match(/^(\+|\-)\d{2}:\d{2}/)
								if(!data) break parsing																			
								 
								if(z != null && z !== data[0].replace(":", ""))	throw jsl.DateError("lang.InconsistentDate:s(z)")
								z	= data[0]
								break
							
							case "za":
								data = ds.match(/^\w+/)								
								if(!data) break parsing																			
								 
								if(za != null && za !== data[0])	throw jsl.DateError("lang.InconsistentDate:s(za)")
								za	= data[0]
								break
															
							default:
								//when is matched the end of the string
								break parsing
						}
							
						ds = ds.slice(data[0].length)							
						li = re.lastIndex
					}
					
					//data string completly consumed
					if(!ds) {
						
						dt = new Date									

						if(H != null)										h = H 
						else if(h != null && mr === 1) 	h	= h === 12 ? 0 : h
						else if(h != null && mr === 2) 	h	= h === 12 ? h : h + 12
						else														h = null
																																											
						if(dw != null && wy != null) {
							
							//iso8601
							n 	= (new Date(y || dt.getFullYear(), 0, 1)).getDay() - l.d_first_wday											
							wy	= n <= 3 ? wy - 1 : wy														
							dt2	= new Date(y || dt.getFullYear(), 0, ((wy - 1) * jsl.Date.WEEK) / jsl.Date.DAY + dw + 7 - n)
														
							d1 	= dt2.getDate()
							m1 	= dt2.getMonth()
							
							if(d != null && d !== d1)	throw jsl.DateError("lang.InconsistentDate:s(d)")
							if(m != null && m !== m1)	throw jsl.DateError("lang.InconsistentDate:s(m)")
							
							d = d1
							m = m1							
						}

						if(dy != null) {
							data 	= new Date(y || dt.getFullYear(), 0, dy)

							if(d != null && d !== data.getDate())		throw jsl.DateError("lang.InconsistentDate:s(d)")
							if(m != null && m !== data.getMonth())	throw jsl.DateError("lang.InconsistentDate:s(d)")
							
							d = data.getDate()
							m = data.getMonth()
						}

						if(dw != null && wm != null) { 
							d1 = (wm - 1) * 7 + dw + 1 + 7 - (new Date(y || dt.getFullYear(), m != null ? m : dt.getMonth())).getDay()
							
							if(d != null && d !== d1)	throw jsl.DateError("lang.InconsistentDate:s(d)")
							d = d1
						}
												
						rv = new Date(
														y 	!= null ? y 	: dt.getFullYear(), 
														m 	!= null ? m 	: dt.getMonth(), 
														d 	!= null ? d 	: dt.getDate(), 
														h 	!= null ? h 	: dt.getHours(),
														mn 	!= null ? mn 	: dt.getMinutes(),
														sn	!= null ? sn	: dt.getSeconds(),
														ms	!= null ? ms 	: dt.getMilliseconds())
						
						
						if(d != null 	&& d !== rv.getDate())				throw jsl.DateError("lang.InconsistentDate:s(d)")
						if(dy === 366 && !jsl.Date.isLeapYear(rv))	throw jsl.DateError("lang.InconsistentDate:s(dy)")
						if(dw != null	&& dw !== rv.getDay())				throw jsl.DateError("lang.InconsistentDate:s(dw)")
														
						break
					}
				}
		
			if(!rv)	throw jsl.DateError("NotRecognized:s")
			return rv	
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.setFormat = function(fid, pattern) {
		try {
			//@d[
			if(arguments.length !== 2)	throw jsl.ParamError()
			jsl.validate(fid		, "s+"	, "fid")
			jsl.validate(pattern, "f|s+", "pattern")//@d]
			
			this.__fs[fid] = jsl.isFunction(pattern) ? pattern : pattern + ""
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.getFormat = function(fid) {
		try {
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(fid, "s+", "fid")
			if(!this.__fs[fid])	throw jsl.ParamError("NotDefined", [fid])//@d]
			
			return this.__fs[fid]
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.isDate = function(s, fid) {
		try {
			var b
						
			try 			{ b = jsl.Date.fromLString.apply(this, arguments)	}
			catch(e) 	{ if(e instanceof jsl.ParamError)					throw e.clearStackTrace()	
									else if(!(e instanceof jsl.DateError))	throw e	}
			
			return !!b
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.setLocale = function(id) {
		try {
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(id, "s+", "id")//@d]
			
			if(this.__l != id)  {

				jsl.require("locale")							
				//@d[
				if(arguments.length && !jsl.Locale.isDefined(id))	throw jsl.ParamError("NotDefined:id")//@d]
				
				//force the normalization of the id
				this.__l = id ? jsl.Locale.get(id).id : jsl.Locale.getCurrent()			
			}
			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getLocale = function() {
		try {
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			if(!this.__l) {			
				jsl.require("locale")			
				this.__l = jsl.Locale.getCurrent()
			}			

			return this.__l
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.setFormat = function(fid) {
		try {
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(fid, "f|s+", "fid")//@d]
			
			if(fid != this.__f)
				if(fid == null)	this.__f = null
				else						this.__f = jsl.isFunction(fid) ? fid : fid + ""

			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getFormat = function() {
		try {
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]			
			return this.__f	|| null
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.toLString = function(fid) {
		try {
			var fm, rv, re, l, d
			
			//@d[			
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(fid, "f|s+", "fid")//@d]

			l = jsl.Date.getLocale(this)
			l = jsl.Locale.get(l)
			
			//1° - default custom format
			if(!fid && this.__f) 
				if(jsl.isFunction(this.__f))										fm = this.__f
				else if(jsl.Date.__fs.hasOwnProperty(this.__f))	fm = jsl.Date.__fs[this.__f] || l.d_formats[this.__f]	 
				else																						fm = this.__f 				
			
			//2° - default locale format	
			else if(!fid && !this.__f) 				
				fm = l.d_formats.date				
			
			//3° - inline function format
			else if(jsl.isFunction(fid))	{
				try 			{ rv = fid(new Date(+this))										}
				catch(e) 	{ throw jsl.ScriptError("BadScript:fid:", e) 	}
				
				//@d[
				if(!jsl.isString(rv))	throw jsl.ParamError("BadReturnValue:fid:string")//@d]
				rv += ""
			}
			
			//4° - inline format id
			else if(jsl.Date.__fs.hasOwnProperty(fid)) {
			
				fm = jsl.Date.__fs[fid]
				if(!fm) fm = l.d_formats[fid]										
			}
			
			//5° - inline locale
			else if(jsl.Locale.isDefined(fid))
				fm = jsl.Locale.get(fid).d_formats.date
			
			//6° - inline string format 
			else 
				fm = fid															
			
			if(rv == null)
			if(jsl.isFunction(fm)) {
				try 			{ rv = fm(+this)																	}
				catch(e) 	{ throw jsl.ScriptError("BadScript:formatter", e) }
	
				//@d[									
				if(!jsl.isString(rv))	throw jsl.ParamError("BadReturnType:formatter:string")//@d]	
				rv += ""			
			}
						
			else {			
				re = 	"(\\\\)*(DAY|Day|day|dyy|DY|Dy|dy|MONTH|Month|month|MT|Mt|mt|MR|mr|hh|h|HH|H|mmn|mn|sf|ss|s|mms|ms|dw|ddw|" +
							"ddy|dd|d|wm|wwm|wy|wwy|mm|m|yyyy|yy|y|za|zs|z:|z)"
				
				re 	= RegExp(re, "g")
				d		= this
								
				rv 	= fm.replace(re, function(m, g1, g2) {
					var v
					
					if(g1 && g1.length % 2) 
						return m
						
					switch(g2) {
						
						case "DAY":		v = l.d_days[d.getDay()].toUpperCase();														break
						case "day":		v = l.d_days[d.getDay()].toLowerCase();														break
						case "Day":		v = l.d_days[d.getDay()];																					break
						
						case "DY":		v = l.d_days_short[d.getDay()].toUpperCase();											break
						case "dy":		v = l.d_days_short[d.getDay()].toLowerCase();											break
						case "Dy":		v = l.d_days_short[d.getDay()];																		break

						case "dw": 		v = jsl.Date.getDayOfWeek(this);																	break
						case "ddw": 	v = "0" + jsl.Date.getDayOfWeek(this);														break

						case "d": 		v = d.getDate();																									break
						case "dd": 		v = jsl.String.padLeft(d.getDate() + "", 2, "0");									break
						
						case "dyy": 	v = jsl.Date.getDayOfYear(this);																	break
						case "ddy": 	v = jsl.String.padLeft(jsl.Date.getDayOfYear(this) + "", 3, "0");	break
						
						case "sf":		v = l.d_days_ordinals[this.getDate()] || l.d_days_ordinals[0];		break	
																																																	
						//-------------------------------------------------------------------------------
						case "wm": 		v = jsl.Date.getWeekOfMonth(this);																break
						case "wwm": 	v = jsl.String.padLeft(jsl.Date.getWeekOfMonth(this) + "", 2,"0");break
 		 				
						case "wy": 		v = jsl.Date.getWeekOfYear(this);																	break
						case "wwy": 	v = jsl.String.padLeft(jsl.Date.getWeekOfYear(this) + "", 2, "0");break

						//-------------------------------------------------------------------------------
						case "MONTH": v = l.d_months[d.getMonth()].toUpperCase(); 											break
						case "month": v = l.d_months[d.getMonth()].toLowerCase(); 											break
						case "Month": v = l.d_months[d.getMonth()]; 																		break

						case "MT": 		v = l.d_months_short[d.getMonth()].toUpperCase(); 								break
						case "mt": 		v = l.d_months_short[d.getMonth()].toLowerCase(); 								break
						case "Mt": 		v = l.d_months_short[d.getMonth()]; 															break

						case "m": 		v = d.getMonth() + 1;																							break
						case "mm": 		v = jsl.String.padLeft(d.getMonth() + 1 + "", 2, "0");						break

						//-------------------------------------------------------------------------------
						case "y": 		v = +(d.getFullYear() + "").slice(2) + "";												break
						case "yy": 		v = (d.getFullYear()	+ "").slice(2);															break
						case "yyyy": 	v = d.getFullYear()	+ "";																					break

						//-------------------------------------------------------------------------------
						case "MR": 		v = l[d.getHours() >= 12 ? "pm" : "am" ].toUpperCase();		 				break
						case "mr": 		v = l[d.getHours() >= 12 ? "pm" : "am" ]; 												break

						case "h": 		v = d.getHours() % 12 || 12;																			break
						case "hh": 		v = jsl.String.padLeft((d.getHours() % 12 || 12) + "", 2, "0");		break
						case "H": 		v = d.getHours();																									break
						case "HH": 		v = jsl.String.padLeft(d.getHours() + "", 2, "0");								break

						case "mn": 		v = d.getMinutes();																								break
						case "mmn": 	v = jsl.String.padLeft(d.getMinutes() + "", 2, "0");							break

						case "s": 		v = d.getSeconds();																								break
						case "ss": 		v = jsl.String.padLeft(d.getSeconds() + "", 2, "0");							break

						case "ms": 		v = d.getMilliseconds();																					break
						case "mms": 	v = jsl.String.padLeft(d.getMilliseconds() + "", 3, "0");					break

						//-------------------------------------------------------------------------------
						case "z": 		v = jsl.Date.getTimeZone(d).offsetS.replace(":", "");							break
						case "zs": 		v = jsl.Date.getTimeZone(d).offsetS.slice(0, 3);									break
						case "z:": 		v = jsl.Date.getTimeZone(d).offsetS;															break
						case "za": 		v = jsl.Date.getTimeZone(d).abbreviation;													break						
					}
										
					return (g1 || "") + v
				})
			}
																																							
			return rv				
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.useDst = function() {
		try {
			var cy, d1, d2 
			
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			cy = this.getFullYear()			
			d1 = new Date(cy, 0, 1)
			d2 = new Date(cy, 5, 1)
			
			return d1.getTimezoneOffset() !== d2.getTimezoneOffset()
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.isInDst = function() {
		try {
			var cy, d1, d2, d3, dn, t1, t2, t3, b 
			
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			cy = this.getFullYear()			
			d1 = new Date(cy, 0, 1)
			d2 = new Date(cy, 5, 1)
			d3 = this

			t1 = d1.getTimezoneOffset()
			t2 = d2.getTimezoneOffset()
			t3 = d3.getTimezoneOffset()
			dn = t1 - t2
			
			if(dn > 0)			b = t3 === t2
			else if(dn < 0)	b = t3 === t1
			else						b = false
			
			return b
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getDstStart = function() {
		try {
			var d1, d2, y, d, hsp, ld1, h
			
			//@d[
			if(!jsl.isDate(this))				throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)				throw jsl.ParamError()
			if(!jsl.Date.useDst(this))	throw jsl.MisuseError("lang.DstNotUsed")//@d]
			
			y		= this.getFullYear()
			d1 	= new Date(y, 0, 1)			
			d2 	= new Date(y, 5, 1)			
			hsp	= d1.getTimezoneOffset() - d2.getTimezoneOffset() 
			h		= jsl.Date.HOUR

			if(hsp < 0)	{		
				d 	= d1		
				d1	= d2
				d2 	= d
				d2.setDate(31, 11)
			}			
				
			while(d2 - d1 > h) {
								
				if(d2.getTimezoneOffset() === d1.getTimezoneOffset())	{ 
					d2 = d1
					d1 = ld1 
				} 
				else {
					ld1 = new Date(+d1)
					d1.setMilliseconds(Math.round((d2 - d1) / 2))
				}
			}				
			
			return d2
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getDstEnd = function() {
		try {
			var d1, d2, y, d, hsp, ld1, h
			
			//@d[
			if(!jsl.isDate(this))				throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)				throw jsl.ParamError()
			if(!jsl.Date.useDst(this))	throw jsl.MisuseError("lang.DstNotUsed")//@d]
			
			y		= this.getFullYear()
			d1 	= new Date(y, 5	, 1)			
			d2 	= new Date(y, 11, 31)			
			hsp	= d2.getTimezoneOffset() - d1.getTimezoneOffset() 
			h		= jsl.Date.HOUR
	
			if(hsp < 0)	{		
				d 	= d1		
				d1	= d2
				d2 	= d
				d2.setFullYear(y + 1)
			}			
				
			while(d2 - d1 > h) {
								
				if(d2.getTimezoneOffset() === d1.getTimezoneOffset())	{ 
					d2 = d1
					d1 = ld1 
				} 
				else {
					ld1 = new Date(+d1)
					d1.setMilliseconds(Math.round((d2 - d1) / 2))
				}
			}				
			
			d1.setHours(d1.getHours() - 1)
			return d1
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getTimeZone = function(dst) {
		try {			
			var tzs, isInDst, dstz, tzo, ds, h, m, jslS
			
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(dst, "b", "dst")//@d]
						
			jsl.require("locale")			

			tzs			=	jsl.Locale.get().d_tzs			
			isInDst	=	jsl.Date.isInDst(this)					
			dstz 		= dst == null ? isInDst : dst			
			tzo			= -this.getTimezoneOffset()				
			tzo			= isInDst ? tzo - 60 : tzo
			ds			= tzs[tzo].split(":")
			tzo			= dstz ? tzo + 60 : tzo
			
			//@d[
			if(dst && !ds[1])	throw jsl.ParamError("BadValue:dst")//@d]
			
			h 		= ~~(tzo / 60)
			m 		= Math.abs(tzo % 60)
			jslS	= jsl.String
								
			return { 	
								abbreviation: dstz ? ds[1] : ds[0], 			
								offsetS:  		(h > 0 ? "+" : "-") + jslS.padLeft(h + "", 2, "0") + ":" + jslS.padLeft(m + "", 2, "0"),
								offsetN: 			tzo,
								offsetH: 			h, 
								offsetM: 			m
						 }
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.move = function(units, clone) {
		try {
			var n, u, re, d, i, map, jsld, rv
				
			//@d[
			if(!jsl.isDate(this))													throw jsl.TypeError("BadMethodCall:Date")
			if(!arguments.length || arguments.length > 2)	throw jsl.ParamError()
			jsl.validate(units, "i|s+", "units")
			if(arguments.length === 2)	jsl.validate(clone, "b", "clone")//@d]
			
			n 		=	0
			u 		= jsl.isString(units) ? units : units + "d"
			re		= /((?:\+|\-)?\d+)(mn|ms|[ymwdhs])/gi
			jsld	= jsl.Date
			map		= { y: jsld.YEAR, m: 	jsld.MONTH	, w: jsld.WEEK	, d: 	jsld.DAY, 
								h: jsld.HOUR, mn: jsld.MINUTE	, s: jsld.SECOND, ms: jsld.MILLISECOND }

			//the same problem of some browser versions
			re.lastIndex = 0
			do {
				
				i = re.lastIndex
				d	= re.exec(u)				
				//@d[
				if(d == null || d.index !== i)	throw jsl.ParamError("BadSyntax:units")//@d]			
				
				n += d[1] * map[d[2]] 
			} while(i + d[0].length < units.length)
			
			rv = clone && clone.valueOf() ? new Date(this) : this
		 	rv.setMilliseconds(this.getMilliseconds() + n)
											
			return rv			
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.toFirstDayOfWeek = function(clone) {
		try {
			var i, l, rv
			
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(clone, "b", "clone")//@d]						
			
			l = jsl.Date.getLocale(this)
			i	= jsl.Locale.get(l).d_first_wday 
			
			rv = clone && clone.valueOf() ? new Date(this) : this 
			rv.setMilliseconds(this.getMilliseconds() - (this.getDay() - i) * jsl.Date.DAY)
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.toLastDayOfWeek = function(clone) {
		try {
			var i, l, rv
			
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(clone, "b", "clone")//@d]
			
			l = jsl.Date.getLocale(this)
			i	= jsl.Locale.get(l).d_first_wday

			rv = clone && clone.valueOf() ? new Date(this) : this 
			rv.setMilliseconds(this.getMilliseconds() + (6 - this.getDay() + i) * jsl.Date.DAY)
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.toFirstDayOfMonth = function(clone) {
		try {
			var rv
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")			
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(clone, "b", "clone")//@d]
			
			rv = clone && clone.valueOf() ? new Date(this) : this 
			rv.setDate(1)			
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.toLastDayOfMonth = function(clone) {
		try {
			var rv
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(clone, "b", "clone")//@d]
			
			rv = clone && clone.valueOf() ? new Date(this) : this 
			rv.setDate(jsl.Date.getDaysOfMonth(this))
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.toFirstDayOfYear = function(clone) {
		try {
			var rv
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(clone, "b", "clone")//@d]
			
			rv = clone && clone.valueOf() ? new Date(this) : this 
			rv.setMonth(0, 1)
			return rv			
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}		
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.toLastDayOfYear = function(clone) {
		try {
			var rv
			//@d[
			if(!jsl.isDate(this))			throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(clone, "b", "clone")//@d]
			
			rv = clone && clone.valueOf() ? new Date(this) : this 
			rv.setMonth(11, 31)
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.isInLeapYear = function() {
		try {
			var y, f, l, ly
			
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			y = this.getFullYear() + ""
			f	= +y.slice(0, 2)
			l = +y.slice(2)
			
			if(l === "00")	ly = !(f / 4)
			else						ly = !(l % 4)
			
			return ly
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.between = function(date1, date2) {
		try {
			//@d[
			if(!jsl.isDate(this))				throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length !== 2)	throw jsl.ParamError()
			jsl.validate(date1, "d", "date1")
			jsl.validate(date2, "d", "date2")//@d]
						
			return date1 <= this && this <= date2
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.distance = function(date, unit) {
		try {
			var u, n, dms, d
			
			//@d[
			if(!jsl.isDate(this))													throw jsl.TypeError("BadMethodCall:Date")
			if(!arguments.length || arguments.length > 2)	throw jsl.ParamError()
			jsl.validate(date	, "d"	, "date")
			if(arguments.length === 2)	jsl.validate(unit, "s+", "unit")//@d]
			
			u 	= unit ? unit.toLowerCase() : "d"
			d		= jsl.Date
			dms	= Math.abs(this - date)			
						
			if			(u === "y")		n = dms	/ d.YEAR					
			else if	(u === "m")		n = dms / d.MONTH
			else if	(u === "w")		n = dms / d.WEEK
			else if	(u === "d")		n	= dms / d.DAY
			else if	(u === "h")		n = dms / d.HOUR
			else if	(u === "mn")	n = dms / d.MINUTE
			else if	(u === "s")		n = dms / d.SECOND
			else if	(u === "ms")	n = dms 
			//@d[
			else throw jsl.ParamError("BadValue:unit")//@d]
						
			return n
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getDaysOfMonth = function() {
		try {
			var ds, i
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			ds 	= [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
			i		= this.getMonth()
			
			return i == 1 && jsl.Date.isInLeapYear(this) ? 29 : ds[i]
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getDaysOfYear = function() {
		try {
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]
			return jsl.Date.isInLeapYear(this) ? 366 : 365			
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getDayOfWeek = function() {
		try {
			var l, d, i			
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			l = jsl.Date.getLocale(this)
			l	= jsl.Locale.get(l)
			i = l.d_first_wday
			d = this.getDay()
			
			return d >= i ? d - i + 1 : 8 - i + d
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getDayOfYear = function() {
		try {
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]

			return Math.floor((this - new Date(this.getFullYear(), 0, 1) + jsl.Date.DAY) / jsl.Date.DAY)
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getWeekOfMonth = function() {
		try {
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]

			return Math.ceil((this.getDate() * jsl.Date.DAY) / jsl.Date.WEEK)
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
  //-------------------------------------------------------------------------------
	jsl.Date.prototype.getWeekOfYear = function() {
		try {
			var n, d
			
			//@d[
			if(!jsl.isDate(this))	throw jsl.TypeError("BadMethodCall:Date")
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			n = (new Date(this.getFullYear(), 0, 1)).getDay()
			d	=  new Date(this.getFullYear(), 0, 7 - n)
			
			return Math.ceil((this - d) / jsl.Date.WEEK) + (n <= 3 ? 1 : 0)						
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
	//Date init
	//-------------------------------------------------------------------------------
	;(function() {
		
		var proto
				
		//-------------------------------------------------------------------------------
		jsl.Date.__native	= jsl.Object.__native.copy().merge(jsl.Date.prototype)
		proto 							= jsl.Date.prototype
		
		for(var id in proto) 
			if(proto.hasOwnProperty(id)) 
				if(id.charAt(0) !== "_" && jsl.isFunction(proto[id]) && !proto[id].__name && id !== "setFormat" && id !== "getFormat") {
					
					jsl.Date[id] = function(obj) { 
						try {
							//@d[
							if(!arguments.length)	throw jsl.ParamError() 
							if(obj === null)			throw jsl.ParamError("NullValue:obj")
							//@d]
							
							return arguments.callee.__f.apply(obj, Array.prototype.slice.call(arguments, 1)) 
						}
						catch(e) {
							jsl.throwError(e, this, arguments)
						}
					}
						
					jsl.Date[id].__name	= id
					jsl.Date[id].__f		= proto[id]
					proto[id].__name 		= id
				}					
	})() 
					